package 线程.线程同步;
/*
    1.在多线程编程时，一些敏感数据不允许被多个线程同时访问，此时就使用同步访问技术
        保证数据在任何同一时刻，最多有一个线程访问，以保证数据的完整性
    2.也可以这样理解：线程同步，即当有一个线程在对内存进行操作时，其他线程都不可以
        对这个内存地址进行操作，直到该线程完成操作，其他线程才能对该内存地址操作

     3.同步代码块
        synchronized(对象) {//得到对象的锁，才能操作同步代码
            需要被同步的代码
        }
     4.synchronized还可以放在方法声明中，便是整个方法为同步方法
        public synchronized void m(String name){
            //需要被同步的代码
        }
 */
public class 线程同步机制 {
    public static void main(String[] args) {
        ticket1 ticket1 = new ticket1();
        new Thread(ticket1).start();
        new Thread(ticket1).start();
        new Thread(ticket1).start();
    }
}

class ticket1 implements Runnable{
    private static int nums = 300;
    private boolean loop = true;
    public void sell(){
        synchronized (this) {
            if (nums <= 0) {
                System.out.println("窗口" + Thread.currentThread().getName() + "票已经售完");
                loop = false;
                return;
            }
            try {
                Thread.sleep(80);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + "卖了一张票"
                    + "\t剩余 " + --nums + "张票");
        }
    }
    @Override
    public void run() {
        while (loop){
            sell();
        }

    }
}
